#pragma once

#include "AST.h"
#include "Error.h"
#include "Lexer.h"
#include "Token.h"
#include "TypeDef.h"

namespace FlooP
{
	class Parser
	{		
		public:

		Parser (Lexer& lexer);

		std::shared_ptr<AST> parse_program ();

		private:

		void do_procedure (std::vector<std::shared_ptr<ASTProcedure>>&  procedure);

		std::shared_ptr<ASTStatement> do_stmt ();
		std::shared_ptr<ASTStatement> do_block ();
		std::shared_ptr<ASTStatement> do_if ();
		std::shared_ptr<ASTStatement> do_loop ();
		std::shared_ptr<ASTStatement> do_muloop ();
		std::shared_ptr<ASTStatement> do_quit ();
		std::shared_ptr<ASTStatement> do_abort ();
		std::shared_ptr<ASTStatement> do_assignment ();

		std::shared_ptr<ASTExpression> do_expr  ();
		std::shared_ptr<ASTExpression> do_expr1 ();
		std::shared_ptr<ASTExpression> do_expr2 ();
		std::shared_ptr<ASTExpression> do_expr3 ();
		std::shared_ptr<ASTExpression> do_expr4 ();
		std::shared_ptr<ASTExpression> do_expr5 ();
		std::shared_ptr<ASTExpression> do_expr6 ();

		bool match (Token::Type type);
		Token require (Token::Type type);
		Token consume ();

		Lexer& m_lexer;

		Token m_buffer[4];

		std::map<Token::Type, std::string> m_token_helpers;
	};
}